package vista;

import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.util.*;
import java.util.Timer;

import javax.swing.*;

import controlador.AccionPausarCarrera;
import controlador.ControlCarrera;
import modelo.Juego;
import modelo.Auto;
import modelo.Motor;
import modelo.Ruedas;
import modelo.Carrera;
import excepciones.RuedasRotasException;


public class PantallaCarrera extends PantallaDeJuego implements Observer{

	/**
	 * El control carrera que controlar� la carrera en esta vista.
	 */
	private ControlCarrera control;
	
	/**
	 * El canvas carrera donde se dibujar� la carrera.
	 */
	private CanvasCarrera canvasCarrera;
	private CanvasVelocimetro canvasVelocimetro;
	private CanvasVidaUtil canvasVidaUtilRuedas;
	private CanvasTablero canvasTablero;
	
	//algunas constantes
	
	//el tama�o de la vista
	private static final int ANCHO = 800;
	private static final int ALTO = 800;
	
	private BufferedImage buffer = new BufferedImage(ANCHO, ALTO, BufferedImage.TRANSLUCENT);

	//private Carrera carrera = Juego.getInstancia().getCarrera();
	private Carrera carrera ;
	public PantallaCarrera(){
		carrera = Juego.getInstancia().getCarrera();
		carrera.addObserver(this);
		//le asigna el keyListener 
		control = new ControlCarrera(carrera);
		addKeyListener(control);
		addKeyListener(new EscListener(carrera));
		
		this.setTitle("Carrera");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setBounds(0, 0, ANCHO, ALTO);
		System.out.println("pantalla carrera");
		inicializarVista();
	}
	
	private void inicializarVista() {
		Auto auto = carrera.getJugador().getAuto();
		System.out.println("inicializar vista");
		canvasCarrera = new CanvasCarrera(carrera);
		canvasVelocimetro = new CanvasVelocimetro(auto);
		canvasVidaUtilRuedas = new CanvasVidaUtil(auto.getRuedas());
		canvasTablero = new CanvasTablero();
		
//		this.getContentPane().add(canvasCarrera);
		canvasTablero.setPosicion(0, 500);
		int posicionX = 50;
		int posicionY = canvasTablero.getHeight() - canvasVelocimetro.getHeight();
		canvasVelocimetro.setPosicion(posicionX, posicionY);
		posicionX += canvasVelocimetro.getWidth() + 10;
		posicionY += 40;
		canvasVidaUtilRuedas.setPosicion(posicionX, posicionY);
		posicionY += canvasVidaUtilRuedas.getHeight() + 5;
		canvasTablero.agregarComponente(canvasVelocimetro);
		canvasTablero.agregarComponente(canvasVidaUtilRuedas);
		this.getContentPane().add(canvasTablero);
		setLocationRelativeTo(null);
	}

	@Override
	public void update(Observable o, Object excepcionLanzada) {
		System.out.println("Pantalla Carrera update");
		if (!carrera.termino()){
			paint(getContentPane().getGraphics());
		}
		else { //la carrera se termin�, ya sea porque ocurri� un error, o porque llego a la meta
			if (excepcionLanzada == null){ //gan� 
				if (carrera.gano()){
					PantallaPrincipal.mostrarPantalla(PantallaPrincipal.pantallaVictoria);
				}
				else {
					PantallaPrincipal.mostrarPantalla(PantallaPrincipal.pantallaDerrota);
				}
			}
			else { //ocurri� un error fatal de juego.. avisar por pantalla...
				Exception e = (Exception) excepcionLanzada;
				PantallaCarreraTerminadaError pantallaError = PantallaPrincipal.pantallaCarreraTerminadaError;
				if (e instanceof RuedasRotasException){
					pantallaError.setMensajeError( ((RuedasRotasException) e).getMessage() );
					PantallaPrincipal.mostrarPantalla(pantallaError);
//				} else if (e instanceof TarjetaSinFondosException){ //el juegador perdi� y se qued� sin plata, pierde el juego
//					PantallaPrincipal.mostrarPantalla(PantallaPrincipal.pantallaGameOver);
				}else {
					pantallaError.setMensajeError("Eror 404: not found ... excepcion: " + e.getClass().getSimpleName());
					PantallaPrincipal.mostrarPantalla(pantallaError);
				} 
			}
			}
		
	
	}
	

	@Override
	public void paint(Graphics g) {
		super.paint(g);
		canvasCarrera.paint(g);
		canvasTablero.paint(g);
	}
	
	@Override
	public void actualizar(){
//		inicializarVista();
//		carrera.deleteObserver(this);
//		carrera = Juego.getInstancia().getCarrera();
//		carrera.addObserver(this);
//		canvasCarrera.actualizar(carrera);
//		Auto auto = carrera.getJugador().getAuto();
//		canvasVelocimetro.setAuto(auto);
//		canvasVidaUtilRuedas.setComponente(auto.getRuedas());
	}
	
	@Override
	public int getHeight(){
		return ALTO;
	}
	
	@Override
	public int getWidth(){
		return ANCHO;
	}
	
	private class EscListener implements KeyListener{
		
		private Carrera carrera;
		
		public EscListener(Carrera carrera) {
			this.carrera = carrera;
		}

		@Override
		public void keyPressed(KeyEvent e) {
			if (e.getKeyCode() == KeyEvent.VK_ESCAPE){
				(new AccionPausarCarrera(carrera)).actuar();
				PantallaPrincipal.mostrarPantalla(PantallaPrincipal.pantallaMenuCarrera);
			}
		}

		@Override
		public void keyReleased(KeyEvent arg0) {}
		@Override
		public void keyTyped(KeyEvent arg0) {}
		
	}

	public void setCarrera(Carrera carrera) {
		this.carrera.deleteObserver(this);
		this.carrera = carrera;
		this.carrera.addObserver(this);
	};
	

	private java.util.Timer timerCuenta = new Timer();
	private static final int CUENTA_INICIAL = 3;
	private static final int RETARDO_COMIENZO = 3000; //miliseg
	private int cuenta;
	
	public void comenzarCarrera() {
		control.habilitar(false);
		carrera.comenzar();
		cuenta = CUENTA_INICIAL;
		timerCuenta.scheduleAtFixedRate(new ContadorCarreraTask(), 0, RETARDO_COMIENZO / CUENTA_INICIAL);
	}
	
	private class ContadorCarreraTask extends TimerTask {

		@Override
		public void run() {
			if (cuenta > 0){
				canvasCarrera.setCuentaActivada(true);
				canvasCarrera.setCuenta(cuenta);
				cuenta--;
			} else { //0
				canvasCarrera.setCuentaActivada(false);
				control.habilitar(true);
				carrera.getJugador().getAuto().acelerar();
				this.cancel();
			}
		}
	}
}
